package com.imut.lagain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imut.lagain.entity.SystemNotification;
import com.imut.lagain.repository.SystemNotificationRepository;
import com.imut.lagain.service.SystemNotificationService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 系统通知服务实现类
 */
@Service
public class SystemNotificationServiceImpl implements SystemNotificationService {
    private static final Logger log = LoggerFactory.getLogger(SystemNotificationServiceImpl.class);
    
    @Autowired
    private SystemNotificationRepository notificationRepository;
    
    @Override
    @Transactional
    public SystemNotification createNotification(Long receiverId, Long triggerUserId, 
                                                String notificationType, String title, 
                                                String content, Long resourceId, 
                                                String resourceType, Integer priority) {
        log.info("创建通知: receiverId={}, type={}, title={}", receiverId, notificationType, title);
        
        SystemNotification notification = new SystemNotification();
        notification.setReceiverId(receiverId);
        notification.setTriggerUserId(triggerUserId);
        notification.setNotificationType(notificationType);
        notification.setTitle(title);
        notification.setContent(content);
        notification.setResourceId(resourceId);
        notification.setResourceType(resourceType);
        notification.setPriority(priority != null ? priority : 2);
        notification.setCreateTime(LocalDateTime.now());
        
        notificationRepository.insert(notification);
        
        // 推送实时通知
        pushRealTimeNotification(notification);
        
        return notification;
    }
    
    @Override
    public SystemNotification createCapsuleCreatedNotification(Long receiverId, Long triggerUserId, 
                                                              Long capsuleId, String capsuleTitle) {
        String title = "新胶囊创建";
        String content = String.format("您的伴侣创建了一个新胶囊：%s", capsuleTitle);
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_CAPSULE_CREATED, 
                                title, content, capsuleId, 
                                SystemNotification.RESOURCE_CAPSULE, 2);
    }
    
    @Override
    public SystemNotification createCapsuleOpenedNotification(Long receiverId, Long triggerUserId, 
                                                             Long capsuleId, String capsuleTitle) {
        String title = "胶囊已打开";
        String content = String.format("您的伴侣打开了胶囊：%s", capsuleTitle);
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_CAPSULE_OPENED, 
                                title, content, capsuleId, 
                                SystemNotification.RESOURCE_CAPSULE, 2);
    }
    
    @Override
    public SystemNotification createThiefSuccessNotification(Long receiverId, Long triggerUserId, 
                                                            Long resourceId, String resourceType) {
        String title = "小偷偷取成功";
        String content = "您的伴侣成功偷取了您的一个物品！";
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_THIEF_SUCCESS, 
                                title, content, resourceId, resourceType, 3);
    }
    
    @Override
    public SystemNotification createThiefFailedNotification(Long receiverId, Long triggerUserId, 
                                                           Long resourceId, String resourceType) {
        String title = "小偷偷取失败";
        String content = "您的伴侣尝试偷取您的物品，但被发现了！";
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_THIEF_FAILED, 
                                title, content, resourceId, resourceType, 2);
    }
    
    @Override
    public SystemNotification createPartnerBoundNotification(Long receiverId, Long partnerId) {
        String title = "伴侣绑定成功";
        String content = "恭喜！您已成功绑定伴侣关系。";
        
        return createNotification(receiverId, null, 
                                SystemNotification.TYPE_PARTNER_BOUND, 
                                title, content, partnerId, 
                                SystemNotification.RESOURCE_USER, 3);
    }
    
    @Override
    public SystemNotification createMoodSharedNotification(Long receiverId, Long triggerUserId, 
                                                          Long moodId) {
        String title = "心情分享";
        String content = "您的伴侣分享了新的心情状态。";
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_MOOD_SHARED, 
                                title, content, moodId, 
                                SystemNotification.RESOURCE_MOOD, 2);
    }
    
    @Override
    public SystemNotification createMemoryCreatedNotification(Long receiverId, Long triggerUserId, 
                                                             Long memoryId, String memoryTitle) {
        String title = "新回忆创建";
        String content = String.format("您的伴侣创建了新回忆：%s", memoryTitle);
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_MEMORY_CREATED, 
                                title, content, memoryId, 
                                SystemNotification.RESOURCE_MEMORY, 2);
    }
    
    @Override
    public SystemNotification createLetterReceivedNotification(Long receiverId, Long triggerUserId, 
                                                              Long letterId) {
        String title = "收到新信件";
        String content = "您收到了来自伴侣的一封信件。";
        
        return createNotification(receiverId, triggerUserId, 
                                SystemNotification.TYPE_LETTER_RECEIVED, 
                                title, content, letterId, 
                                SystemNotification.RESOURCE_LETTER, 3);
    }
    
    @Override
    public SystemNotification createPeriodReminderNotification(Long receiverId, String reminderType) {
        String title = "生理期提醒";
        String content;
        
        switch (reminderType) {
            case "PERIOD_START":
                content = "根据预测，您的生理期即将开始，请注意身体健康。";
                break;
            case "PERIOD_END":
                content = "您的生理期即将结束，记得记录相关信息。";
                break;
            case "OVULATION":
                content = "根据预测，您即将进入排卵期。";
                break;
            default:
                content = "生理期相关提醒。";
        }
        
        return createNotification(receiverId, null, 
                                SystemNotification.TYPE_PERIOD_REMINDER, 
                                title, content, null, null, 2);
    }
    
    @Override
    public SystemNotification createSystemUpdateNotification(Long receiverId, String updateContent) {
        String title = "系统更新";
        String content = updateContent;
        
        return createNotification(receiverId, null, 
                                SystemNotification.TYPE_SYSTEM_UPDATE, 
                                title, content, null, null, 1);
    }
    
    @Override
    public IPage<SystemNotification> getUserNotifications(Long userId, int page, int size) {
        Page<SystemNotification> pageParam = new Page<>(page, size);
        return notificationRepository.findByReceiverId(pageParam, userId);
    }
    
    @Override
    public Long getUnreadNotificationCount(Long userId) {
        return notificationRepository.countUnreadNotifications(userId);
    }
    
    @Override
    public List<SystemNotification> getNotificationsByType(Long userId, String type) {
        return notificationRepository.findByReceiverIdAndType(userId, type);
    }
    
    @Override
    public List<SystemNotification> getUnreadNotificationsByType(Long userId, String type) {
        return notificationRepository.findUnreadByReceiverIdAndType(userId, type);
    }
    
    @Override
    @Transactional
    public boolean markAsRead(Long notificationId, Long userId) {
        SystemNotification notification = notificationRepository.selectById(notificationId);
        if (notification == null || !notification.getReceiverId().equals(userId)) {
            return false;
        }
        
        int result = notificationRepository.markAsRead(notificationId, LocalDateTime.now());
        return result > 0;
    }
    
    @Override
    @Transactional
    public boolean markAllAsRead(Long userId) {
        int result = notificationRepository.markAllAsRead(userId, LocalDateTime.now());
        return result >= 0;
    }
    
    @Override
    @Transactional
    public boolean markTypeAsRead(Long userId, String type) {
        int result = notificationRepository.markTypeAsRead(userId, type, LocalDateTime.now());
        return result >= 0;
    }
    
    @Override
    @Transactional
    public boolean deleteNotification(Long notificationId, Long userId) {
        SystemNotification notification = notificationRepository.selectById(notificationId);
        if (notification == null || !notification.getReceiverId().equals(userId)) {
            return false;
        }
        
        notification.setIsDeleted(true);
        int result = notificationRepository.updateById(notification);
        return result > 0;
    }
    
    @Override
    public List<SystemNotification> getNotificationsByTimeRange(Long userId, 
                                                               LocalDateTime startTime, 
                                                               LocalDateTime endTime) {
        return notificationRepository.findByTimeRange(userId, startTime, endTime);
    }
    
    @Override
    public List<SystemNotification> getHighPriorityUnreadNotifications(Long userId, Integer minPriority) {
        return notificationRepository.findHighPriorityUnread(userId, minPriority);
    }
    
    @Override
    public List<SystemNotification> getNotificationsByResource(Long resourceId, String resourceType) {
        return notificationRepository.findByResource(resourceId, resourceType);
    }
    
    @Override
    public List<SystemNotification> getNotificationsByTriggerUser(Long triggerUserId) {
        return notificationRepository.findByTriggerUserId(triggerUserId);
    }
    
    @Override
    public SystemNotification getNotificationById(Long notificationId, Long userId) {
        SystemNotification notification = notificationRepository.selectById(notificationId);
        if (notification == null || !hasPermission(notificationId, userId)) {
            return null;
        }
        return notification;
    }
    
    @Override
    @Transactional
    public int cleanExpiredNotifications(int days) {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(days);
        return notificationRepository.deleteExpiredNotifications(expireTime);
    }
    
    @Override
    public Map<String, Object> getNotificationStatistics(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        // 总通知数
        Long totalCount = notificationRepository.selectCount(
            new LambdaQueryWrapper<SystemNotification>().eq(SystemNotification::getReceiverId, userId));
        
        // 未读通知数
        Long unreadCount = getUnreadNotificationCount(userId);
        
        // 今日通知数
        Long todayCount = getTodayNotificationCount(userId);
        
        // 高优先级未读通知数
        List<SystemNotification> highPriorityUnread = getHighPriorityUnreadNotifications(userId, 3);
        
        stats.put("totalCount", totalCount);
        stats.put("unreadCount", unreadCount);
        stats.put("todayCount", todayCount);
        stats.put("highPriorityUnreadCount", highPriorityUnread.size());
        
        return stats;
    }
    
    @Override
    public List<Map<String, Object>> getNotificationSummary(Long userId, int days) {
        LocalDateTime since = LocalDateTime.now().minusDays(days);
        List<Object> rawResults = notificationRepository.getNotificationSummary(userId, since);
        List<Map<String, Object>> results = new ArrayList<>();
        for (Object obj : rawResults) {
            if (obj instanceof Map) {
                results.add((Map<String, Object>) obj);
            }
        }
        return results;
    }
    
    @Override
    public boolean hasPermission(Long notificationId, Long userId) {
        SystemNotification notification = notificationRepository.selectById(notificationId);
        if (notification == null) {
            return false;
        }
        
        return notification.getReceiverId().equals(userId);
    }
    
    @Override
    @Transactional
    public List<SystemNotification> createBatchNotifications(List<Long> receiverIds, 
                                                            Long triggerUserId, 
                                                            String notificationType, 
                                                            String title, String content, 
                                                            Long resourceId, String resourceType, 
                                                            Integer priority) {
        List<SystemNotification> notifications = new ArrayList<>();
        
        for (Long receiverId : receiverIds) {
            SystemNotification notification = createNotification(receiverId, triggerUserId, 
                                                               notificationType, title, content, 
                                                               resourceId, resourceType, priority);
            notifications.add(notification);
        }
        
        return notifications;
    }
    
    @Override
    public Long getTodayNotificationCount(Long userId) {
        LocalDateTime startOfDay = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
        LocalDateTime endOfDay = startOfDay.plusDays(1);
        
        LambdaQueryWrapper<SystemNotification> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemNotification::getReceiverId, userId)
                   .between(SystemNotification::getCreateTime, startOfDay, endOfDay);
        
        return notificationRepository.selectCount(queryWrapper);
    }
    
    @Override
    public void pushRealTimeNotification(SystemNotification notification) {
        // TODO: 实现WebSocket实时推送
        log.info("推送实时通知: receiverId={}, type={}, title={}", 
                notification.getReceiverId(), notification.getNotificationType(), notification.getTitle());
    }
}